import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

typedef AssertsWidgetBuilder = Widget Function(
    BuildContext context, ImageInfo? imageInfo);

class KqPadSliderComponentShapeImageBuilder extends StatefulWidget {
  final String assertName;
  final String? package;
  final AssertsWidgetBuilder builder;
  const KqPadSliderComponentShapeImageBuilder(
      {required this.assertName,
      required this.builder,
      this.package,
      super.key});

  @override
  State<KqPadSliderComponentShapeImageBuilder> createState() =>
      _KqPadSliderComponentShapeImageBuilderState();
}

class _KqPadSliderComponentShapeImageBuilderState
    extends State<KqPadSliderComponentShapeImageBuilder> {
  ImageInfo? _imageInfo;

  @override
  void initState() {
    super.initState();
    _loadAssertsImage().then((value) {
      setState(() {
        _imageInfo = value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return widget.builder.call(context, _imageInfo);
  }

  Future<ImageInfo?> _loadAssertsImage() {
    final Completer<ImageInfo?> completer = Completer<ImageInfo?>();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      final ImageProvider imageProvider =
          AssetImage(widget.assertName, package: widget.package);
      final ImageConfiguration config = createLocalImageConfiguration(context);
      final ImageStream stream = imageProvider.resolve(config);

      ImageStreamListener? listener;
      listener = ImageStreamListener(
        (ImageInfo? image, bool sync) {
          if (!completer.isCompleted) {
            completer.complete(image);
          }
          SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
            stream.removeListener(listener!);
          });
        },
        onError: (exception, stackTrace) {
          stream.removeListener(listener!);
          completer.completeError(exception, stackTrace);
        },
      );
      stream.addListener(listener);
    });

    return completer.future;
  }
}
